package com.demo.config.datasource.annotation;


import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;


/**
 * @author wangfengchen
 */
//@Configuration
public class DataSourceConfig {


  /**
   * 主数据源
   *
   * @return
   */
  @Bean("masterDataSource")
  @ConfigurationProperties(prefix = "spring.datasource.master")
  public DataSource masterDataSource() {
    return DataSourceBuilder.create().build();
  }

  /**
   * 从数据源
   *
   * @return
   */
  @Bean("slaveDataSource")
  @ConfigurationProperties(prefix = "spring.datasource.slave")
  public DataSource slaveDataSource() {
    return DataSourceBuilder.create().build();
  }

  /**
   * 动态数据源
   *
   * @param masterDataSource
   * @param slaveDataSource
   * @return
   */
  @Bean("dynamicDataSource")
  public DataSource dynamicDataSource(
      @Qualifier("masterDataSource") DataSource masterDataSource,
      @Qualifier("slaveDataSource") DataSource slaveDataSource) {

    Map<Object, Object> targetDataSources = new HashMap<>();
    targetDataSources.put(DynamicDSEnum.MASTER.getDesc(), masterDataSource);
    targetDataSources.put(DynamicDSEnum.SLAVE.getDesc(), slaveDataSource);

    DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
    dynamicRoutingDataSource.setDefaultTargetDataSource(masterDataSource); // 默认数据源
    dynamicRoutingDataSource.setTargetDataSources(targetDataSources);
    return dynamicRoutingDataSource;
  }

  /**
   * 将动态数据源注入到 SqlSessionFactory
   *
   * @param dynamicDataSource
   * @return
   * @throws Exception
   */
  @Bean
  public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) throws Exception {
    MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
    factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*Mapper.xml"));
    factoryBean.setDataSource(dynamicDataSource);
    return factoryBean.getObject();
  }

  /**
   * 动态数据源需与事务管理器配合，否则事务不生效
   *
   * @param dynamicDataSource
   * @return
   */
  @Bean
  public PlatformTransactionManager transactionManager(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) {
    return new DataSourceTransactionManager(dynamicDataSource);
  }


}